package vis.core.service.captcha.impl;

import vis.core.common.cache.Cache;
import vis.core.common.cache.CacheKey;
import vis.core.common.util.Base64;
import vis.core.common.util.IdKit;
import vis.core.common.util.StringKit;
import vis.core.common.util.ThreadKit;
import vis.core.common.valid.Email;
import vis.core.common.valid.Length;
import vis.core.common.valid.base.Valid;
import vis.core.domain.db.SysUser;
import vis.core.domain.sys.MSG;
import vis.core.domain.sys.ServiceException;
import vis.core.mapper.SysUserMapper;
import vis.core.service.captcha.CaptchaService;
import vis.core.service.mail.EmailService;
import com.google.code.kaptcha.Producer;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.FastByteArrayOutputStream;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 验证码操作处理
 */
@Slf4j
@Service
public class CaptchaServiceImpl implements CaptchaService {

    @Resource(name = "captchaProducer")
    private Producer captchaProducer;

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private EmailService emailService;

    @Resource
    private Cache<String> cache;

    @Valid
    @Override
    public boolean sendEmailRegister(@Email String toEmail) {
        SysUser user = sysUserMapper.selectColumnByKey("email", toEmail, "id");
        if (user != null) throw new ServiceException(MSG.REGISTER_EXISTS);

        String cacheKey = CacheKey.CAPTCHA_EMAIL_REGISTER_CODE.key() + toEmail;
        String s = cache.get(cacheKey);

        if (StringKit.isBlank(s)) {
            String code = StringKit.createRandom(6);
            boolean isSend = emailService.send(toEmail, "ABL平台【注册验证码】", "您的验证码：" + code);
            if (isSend) {
                log.error("给{} ;发送了验证码 {} ;cacheKey {} ", toEmail, code, cacheKey);
                cache.set(cacheKey, code, 600L);
            }
        }

        return true;
    }

    @Override
    public boolean sendPhoneRegister(String toPhone) {
        return false;
    }

    @Valid
    @Override
    public boolean checkEmailRegister(@Email String toEmail, @Length(mast = 6) String captcha) {
        String cacheKey = CacheKey.CAPTCHA_EMAIL_REGISTER_CODE.key() + toEmail;
        String s = cache.get(cacheKey);
        return captcha.equals(s);
    }

    @Override
    public boolean checkPhoneRegister(String toPhone, @Length(mast = 6) String captcha) {
        String cacheKey = CacheKey.CAPTCHA_PHONE_REGISTER_CODE.key() + toPhone;
        String s = cache.get(cacheKey);
        return captcha.equals(s);
    }


    @Valid
    @Override
    public boolean delEmailRegister(@Email String toEmail, @Length(mast = 6) String captcha) {
        String cacheKey = CacheKey.CAPTCHA_EMAIL_REGISTER_CODE.key() + toEmail;
        return cache.delete(cacheKey);
    }

    @Override
    public boolean delPhoneRegister(String toPhone, @Length(mast = 6) String captcha) {
        String cacheKey = CacheKey.CAPTCHA_PHONE_REGISTER_CODE.key() + toPhone;
        return cache.delete(cacheKey);
    }

    /**
     * 生成验证码
     */
    public Map getLoginImg() {
        String id = IdKit.getId();
        String KEY = CacheKey.CAPTCHA_LOGIN_CODE.key() + id;

        // 生成验证码
        String capText = captchaProducer.createText();
        String capStr = capText.substring(0, capText.lastIndexOf("@"));
        String code = capText.substring(capText.lastIndexOf("@") + 1);
        BufferedImage image = captchaProducer.createImage(capStr);

        cache.set(KEY, code, 3 * 60L);

        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        try {
            ImageIO.write(image, "jpg", os);
        } catch (IOException e) {
            throw new ServiceException(MSG.CAPTCHA_IMAGE);
        }

        HashMap<Object, Object> map = new HashMap<>();
        map.put("id", id);
        map.put("img", Base64.encode(os.toByteArray()));

        return map;
    }

    /**
     * 校验
     */
    public boolean checkLogin(String id, String code) {
        String KEY = CacheKey.CAPTCHA_LOGIN_CODE.key() + id;
        String captcha = cache.get(KEY);
        cache.delete(KEY);
        if (captcha == null) {
            ThreadKit.getPool().execute(() -> {
                log.error("异步处理 验证码为空");
            });
            throw new ServiceException(MSG.CAPTCHA_NULL);
        }
        if (!code.equalsIgnoreCase(captcha)) {
            ThreadKit.getPool().execute(() -> {
                log.error("异步处理 比对失败");
            });
            throw new ServiceException(MSG.CAPTCHA_ERROR);
        }
        return true;
    }

}
